const DIALOG_GROW_TIME = 0.1;
-const CommandCompleter = new Lang.Class({
- Name: 'CommandCompleter',
-
- _init : function() {
- this._changedCount = 0;
- this._paths = GLib.getenv('PATH').split(':');
- this._paths.push(GLib.get_home_dir());
- this._valid = false;
- this._updateInProgress = false;
- this._childs = new Array(this._paths.length);
- this._monitors = new Array(this._paths.length);
- for (let i = 0; i < this._paths.length; i++) {
- this._childs[i] = [];
- let file = Gio.file_new_for_path(this._paths[i]);
- let info;
- try {
- info = file.query_info(Gio.FILE_ATTRIBUTE_STANDARD_TYPE, Gio.FileQueryInfoFlags.NONE, null);
- } catch (e) {
- // FIXME catchall
- this._paths[i] = null;
- continue;
- }
-
- if (info.get_attribute_uint32(Gio.FILE_ATTRIBUTE_STANDARD_TYPE) != Gio.FileType.DIRECTORY)
- continue;
-
- this._paths[i] = file.get_path();
- this._monitors[i] = file.monitor_directory(Gio.FileMonitorFlags.NONE, null);
- if (this._monitors[i] != null) {
- this._monitors[i].connect('changed', Lang.bind(this, this._onChanged));
- }
- }
- this._paths = this._paths.filter(function(a) {
- return a != null;
- });
- this._update(0);
- },
-
- update : function() {
- if (this._valid)
- return;
- this._update(0);
- },
-
- _update : function(i) {
- if (i == 0 && this._updateInProgress)
- return;
- this._updateInProgress = true;
- this._changedCount = 0;
- this._i = i;
- if (i >= this._paths.length) {
- this._valid = true;
- this._updateInProgress = false;
- return;
- }
- let file = Gio.file_new_for_path(this._paths[i]);
- this._childs[this._i] = [];
- FileUtils.listDirAsync(file, Lang.bind(this, function (files) {
- for (let i = 0; i < files.length; i++) {
- this._childs[this._i].push(files[i].get_name());
- }
- this._update(this._i + 1);
- }));
- },
-
- _onChanged : function(m, f, of, type) {
- if (!this._valid)
- return;
- let path = f.get_parent().get_path();
- let k = undefined;
- for (let i = 0; i < this._paths.length; i++) {
- if (this._paths[i] == path)
- k = i;
- }
- if (k === undefined) {
- return;
- }
- if (type == Gio.FileMonitorEvent.CREATED) {
- this._childs[k].push(f.get_basename());
- }
- if (type == Gio.FileMonitorEvent.DELETED) {
- this._changedCount++;
- if (this._changedCount > MAX_FILE_DELETED_BEFORE_INVALID) {
- this._valid = false;
- }
- let name = f.get_basename();
- this._childs[k] = this._childs[k].filter(function(e) {
- return e != name;
- });
- }
- if (type == Gio.FileMonitorEvent.UNMOUNTED) {
- this._childs[k] = [];
- }
- },
-
- getCompletion: function(text) {
- let common = '';
- let notInit = true;
- if (!this._valid) {
- this._update(0);
- return common;
- }
- function _getCommon(s1, s2) {
- let k = 0;
- for (; k < s1.length && k < s2.length; k++) {
- if (s1[k] != s2[k])
- break;
- }
- if (k == 0)
- return '';
- return s1.substr(0, k);
- }
- function _hasPrefix(s1, prefix) {
- return s1.indexOf(prefix) == 0;
- }
- for (let i = 0; i < this._childs.length; i++) {
- for (let k = 0; k < this._childs[i].length; k++) {
- if (!_hasPrefix(this._childs[i][k], text))
- continue;
- if (notInit) {
- common = this._childs[i][k];
- notInit = false;
- }
- common = _getCommon(common, this._childs[i][k]);
- }
- }
- if (common.length)
- return common.substr(text.length);
- return common;
- }
-});
-
const RunDialog = new Lang.Class({
Name: 'RunDialog',
Extends: ModalDialog.ModalDialog,
key: Clutter.Escape }]);
this._pathCompleter = new Gio.FilenameCompleter();
- this._commandCompleter = new CommandCompleter();
- this._group.connect('notify::visible', Lang.bind(this._commandCompleter, this._commandCompleter.update));
this._history = new History.HistoryManager({ gsettingsKey: HISTORY_KEY,
entry: this._entryText });
}));
},
+ _getCommandCompletion: function(text) {
+ function _getCommon(s1, s2) {
+ if (s1 == null)
+ return s2;
+
+ let k = 0;
+ for (; k < s1.length && k < s2.length; k++) {
+ if (s1[k] != s2[k])
+ break;
+ }
+ if (k == 0)
+ return '';
+ return s1.substr(0, k);
+ }
+
+ let paths = GLib.getenv('PATH').split(':');
+ paths.push(GLib.get_home_dir());
+ let someResults = paths.map(function(path) {
+ let file = Gio.File.new_for_path(path);
+ let fileEnum = file.enumerate_children('standard::name', Gio.FileQueryInfoFlags.NONE, null);
+ let info;
+ let results = [];
+ while ((info = fileEnum.next_file(null))) {
+ let name = info.get_name();
+ if (name.slice(0, text.length) == text)
+ results.push(name);
+ }
+ return results;
+ });
+ let results = someResults.reduce(function(a, b) {
+ return a.concat(b);
+ }, []);
+ let common = results.reduce(_getCommon, null);
+ return common.substr(text.length);
+ },
+
_getCompletion : function(text) {
if (text.indexOf('/') != -1) {
return this._pathCompleter.get_completion_suffix(text);
} else {
- return this._commandCompleter.getCompletion(text);
+ return this._getCommandCompletion(text);
}
},